package com.pro01.apirednote.service.serviceImpl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.pro01.apirednote.dto.UserSummaryDTO;
import com.pro01.apirednote.mapper.UserMapper;
import com.pro01.apirednote.pojo.PageResult;
import com.pro01.apirednote.pojo.User;
import com.pro01.apirednote.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;
    private final RedisTemplate<String, Object> redisTemplate;
    private final ObjectMapper objectMapper;
    
    // 用户缓存前缀和过期时间
    private static final String USER_ID_PREFIX = "user:id:";
    private static final String USER_NAME_PREFIX = "user:name:";
    private static final long USER_CACHE_EXPIRE_TIME = 30; // 30分钟

    @Override
    public void register(User user) {
        userMapper.insertUser(user);
    }

    @Override
    public User findByUsername(String username) {
        if (username == null || username.trim().isEmpty()) {
            return null;
        }
        
        // 尝试从缓存获取
        String cacheKey = USER_NAME_PREFIX + username;
        try {
            Object cachedUser = redisTemplate.opsForValue().get(cacheKey);
            if (cachedUser != null) {
                log.info("从缓存获取用户数据，username: {}", username);
                
                // 处理不同类型的缓存结果
                if (cachedUser instanceof User) {
                    return (User) cachedUser;
                } else if (cachedUser instanceof java.util.LinkedHashMap) {
                    return objectMapper.convertValue(cachedUser, User.class);
                }
            }
        } catch (Exception e) {
            log.error("获取用户缓存异常，username: {}", username, e);
            // 异常不影响主流程
        }
        
        // 缓存未命中，从数据库获取
        User user = userMapper.selectByUsername(username);
        
        // 将结果存入缓存
        if (user != null) {
            try {
                redisTemplate.opsForValue().set(cacheKey, user, USER_CACHE_EXPIRE_TIME, TimeUnit.MINUTES);
                // 同时以用户ID为键缓存
                redisTemplate.opsForValue().set(USER_ID_PREFIX + user.getId(), user, USER_CACHE_EXPIRE_TIME, TimeUnit.MINUTES);
                log.info("用户数据已缓存，username: {}", username);
            } catch (Exception e) {
                log.error("缓存用户数据异常，username: {}", username, e);
                // 缓存失败不影响主流程
            }
        }
        
        return user;
    }

    @Override
    public boolean existsByUsername(String username) {
        // 先尝试从缓存查找
        User user = findByUsername(username);
        if (user != null) {
            return true;
        }
        
        // 缓存未命中，查询数据库
        return userMapper.countByUsername(username) > 0;
    }

    // 获取当前用户信息
    @Override
    public User getById(Long id) {
        if (id == null) {
            return null;
        }
        
        // 尝试从缓存获取
        String cacheKey = USER_ID_PREFIX + id;
        try {
            Object cachedUser = redisTemplate.opsForValue().get(cacheKey);
            if (cachedUser != null) {
                log.info("从缓存获取用户数据，id: {}", id);
                
                // 处理不同类型的缓存结果
                if (cachedUser instanceof User) {
                    return (User) cachedUser;
                } else if (cachedUser instanceof java.util.LinkedHashMap) {
                    return objectMapper.convertValue(cachedUser, User.class);
                }
            }
        } catch (Exception e) {
            log.error("获取用户缓存异常，id: {}", id, e);
            // 异常不影响主流程
        }
        
        // 缓存未命中，从数据库获取
        User user = userMapper.selectById(id);
        
        // 将结果存入缓存
        if (user != null) {
            try {
                redisTemplate.opsForValue().set(cacheKey, user, USER_CACHE_EXPIRE_TIME, TimeUnit.MINUTES);
                // 同时以用户名为键缓存
                redisTemplate.opsForValue().set(USER_NAME_PREFIX + user.getUsername(), user, USER_CACHE_EXPIRE_TIME, TimeUnit.MINUTES);
                log.info("用户数据已缓存，id: {}", id);
            } catch (Exception e) {
                log.error("缓存用户数据异常，id: {}", id, e);
                // 缓存失败不影响主流程
            }
        }
        
        return user;
    }

    @Override
    public PageResult<User> getAllUsers(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<User> records = userMapper.selectAllUsers(pageSize, offset);
        int total = userMapper.countAllUsers();
        return new PageResult<>(total, records);
    }
    
    // 查询用户列表
    @Override
    public PageResult<UserSummaryDTO> listAllUsers(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<UserSummaryDTO> users = userMapper.findAllUsers(offset, pageSize);
        long total = userMapper.countAllUsers();
        return PageResult.of(total, users);
    }
    
    // 管理员修改用户权限
    @Override
    public boolean updateUserRole(Long id, String role) {
        User user = userMapper.selectById(id);
        if (user == null) return false;
        
        boolean updated = userMapper.updateUserRole(id, role) > 0;
        
        // 如果更新成功，清除缓存
        if (updated) {
            try {
                // 删除以ID为键的缓存
                redisTemplate.delete(USER_ID_PREFIX + id);
                // 删除以用户名为键的缓存
                if (user.getUsername() != null) {
                    redisTemplate.delete(USER_NAME_PREFIX + user.getUsername());
                }
                log.info("用户缓存已清除，id: {}", id);
            } catch (Exception e) {
                log.error("清除用户缓存异常，id: {}", id, e);
                // 清除缓存失败不影响主流程
            }
        }
        
        return updated;
    }
}

